﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Netfraction.Network.Protocol.BASE.Handler
{
    public class HandlerSID : ProtocolMessageActionHandler
    {
        public HandlerSID() : base()
        {
            mSupportedConnectionStates = new List<RemoteMachine.ConnectionState>();
            mSupportedConnectionStates.Add(RemoteMachine.ConnectionState.Protocol);
        }

        #region ProtocolMessageActionHandler Members

        public override string ProtocolActionCode
        {
            get { return "SID"; }
        }

        public override bool HandleProtocolMessage(RemoteMachine.Node node, ProtocolMessage message, IEnumerable<ProtocolFeature> extenders)
        {
            if (node is RemoteMachine.Hub && IsSupportedConnectionState(node))
            {
                if (message.Parameters.Count != 0)
                {
                    message.Parameters = DecodeParameters(message.Parameters);
                    (node as RemoteMachine.Hub).SessionId = message.Parameters[0].ParameterValue;

                    LocalMachine.Client client = LocalMachine.Client.GetInstance();
                    lock (client)
                    {
                        ProtocolMessageFactory factory = new Factory.FactoryINF();

                        Dictionary<int, object> factoryParams = new Dictionary<int, object>();
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.SessionID, (node as RemoteMachine.Hub).SessionId);
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.ClientID, client.Identity.ClientId);
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.PrivateID, client.Identity.PrivateId);
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.NickOrHubName, client.Identity.Nickname);
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.Description, client.Identity.Description);
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.EmailAddress, client.Identity.Email);
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.ClientVersionIdentifier, "Netfraction 0.1");
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.ShareSize, client.Identity.ShareSize.ToString());
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.SharedFilesCount, client.Identity.SharedFilesCount.ToString());
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.MaximumDownloadSpeed, client.Identity.MaximumDownloadSpeed.ToString());
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.MaximumUploadSpeed, client.Identity.MaximumUploadSpeed.ToString());
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.MaximumUploadSlots, client.Identity.UploadSlots);
                        
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.IPv4_Address, 
                            client.Identity.IPv4Address == System.Net.IPAddress.None ? (node as RemoteMachine.Hub).Connection.LocalEndPoint.Address.ToString() : client.Identity.IPv4Address.ToString());
                        /*factoryParams.Add((int)Factory.FactoryINF.GETParameterOptions.IPv6Address, client);
                        factoryParams.Add((int)Factory.FactoryINF.GETParameterOptions.RemoteClientType, client);
                        factoryParams.Add((int)Factory.FactoryINF.GETParameterOptions.UDPv4Port, client);
                        factoryParams.Add((int)Factory.FactoryINF.GETParameterOptions.UDPv6Port, client);
                        factoryParams.Add((int)Factory.FactoryINF.GETParameterOptions.AutomaticSlotAllocatorSpeedLimit, client);
                        factoryParams.Add((int)Factory.FactoryINF.GETParameterOptions.MinimumUploadConnectionsForAutoSlotAlloc, client);*/
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.UserNormalCount, 1);
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.UserRegisteredCount, 0);
                        factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.UserOperatorCount, 0);
                        int awayStatus = Convert.ToInt32(client.Identity.AwayStatus);
                        if (awayStatus > 0)
                        {
                            factoryParams.Add((int)Factory.FactoryINF.ParameterEnum.AwayStatus, awayStatus);
                        }
                        // Send Client Information to Hub
                        (node as RemoteMachine.Hub).Connection.Send(factory.Create(ProtocolMessage.MessageTypeEnum.Broadcast, factoryParams).ToString());
                    }

                    (node as RemoteMachine.Hub).Connection.State = RemoteMachine.ConnectionState.Identify;
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion
    }
}
